/**
 ******************************************************************************
 * @file    timer_PWM.c
 * @author  星辰
 * @version 1.0
 * @date    2022-8-19
 * @brief   使用定时器的PWM模式输出PWM波源文件
 ******************************************************************************
 */

#include <timer_PWM.h>

/**
 * @brief  TIM3输出PWM初始化
 * @note   需要改变PWM占空比时，使用 TIM_SetCompare2(TIM_TypeDef* TIMx, uint16_t Compare2)
 * @param  arr: 自动重装载值。
 *              此参数必须是介于 0x0000 和 0xFFFF 之间的数字。
 * @param  psc: 预分频系数。
 *              此参数可以是 0x0000 和 0xFFFF 之间的数字
 * @retval None
 * @example 输出可变占空比PWM，呼吸灯效果
 *          u16 led0pwmval = 0;
 *          u8 dir         = 1;
 *          TIM3_PWM_init(899, 0); //不分频。PWM频率=72000000/900=80Khz
 *          while (1)
 *          {
 *              delay_ms(10);
 *              if (dir)
 *                  led0pwmval++;
 *              else
 *                  led0pwmval--;
 *
 *              if (led0pwmval > 300) dir = 0;
 *              if (led0pwmval == 0) dir = 1;
 *              TIM_SetCompare2(TIM3, led0pwmval);
 *  }
 */
void TIM3_PWM_init(u16 arr, u16 psc)
{
    GPIO_InitTypeDef GPIO_InitStrue;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    TIM_OCInitTypeDef TIM_OCInitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); ///< 使能GPIOB和AFIO复用功能时钟
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);                        ///< 使能TIM3时钟

    GPIO_InitStrue.GPIO_Mode  = GPIO_Mode_AF_PP; ///< 复用推挽输出
    GPIO_InitStrue.GPIO_Pin   = GPIO_Pin_5;
    GPIO_InitStrue.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStrue); ///< 初始化LED相关引脚

    // 设置TIM３为部分重映射
    // 目的：TIM3_CH2->PB5
    GPIO_PinRemapConfig(GPIO_PartialRemap_TIM3, ENABLE);

    TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;       ///< 时钟分割
    TIM_TimeBaseStructure.TIM_CounterMode   = TIM_CounterMode_Up; ///< 计数模式
    TIM_TimeBaseStructure.TIM_Period        = arr;                ///< 自动重装载值
    TIM_TimeBaseStructure.TIM_Prescaler     = psc;                ///< 预分频系数
    // TIM_TimeBaseStructure.TIM_RepetitionCounter = ;            ///< 重复计数器(定时器中断中用不到)

    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); // 初始化定时器3

    //初始化TIM3 Channel2 PWM模式
    TIM_OCInitStructure.TIM_OCMode      = TIM_OCMode_PWM2;        ///< 模式，PWM2模式
    TIM_OCInitStructure.TIM_OCPolarity  = TIM_OCPolarity_High;    ///< 设置输出的有效极性（高）
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; ///< 比较输出使能

    TIM_OC2Init(TIM3, &TIM_OCInitStructure); ///< 根据指定的参数初始化外设TIM3 OC2

    TIM_OC2PreloadConfig(TIM3, TIM_OCPreload_Enable); ///< 使能TIM3在CCR2上的预装载寄存器

    TIM_Cmd(TIM3, ENABLE); ///< 使能TIM3
}
